/**
 * 文件处理工具
 */

/**
 * 格式化文件大小
 * @param bytes 字节数
 * @returns 格式化后的文件大小
 */
export function formatFileSize(bytes?: number): string {
  if (!bytes || bytes === 0) return '0 B'
  
  const k = 1024
  const sizes = ['B', 'KB', 'MB', 'GB', 'TB']
  const i = Math.floor(Math.log(bytes) / Math.log(k))
  
  return `${(bytes / Math.pow(k, i)).toFixed(2)} ${sizes[i]}`
}

/**
 * 获取文件扩展名
 * @param filename 文件名
 * @returns 扩展名（小写，不含点）
 */
export function getFileExtension(filename: string): string {
  const parts = filename.split('.')
  return parts.length > 1 ? parts[parts.length - 1].toLowerCase() : ''
}

/**
 * 验证文件类型
 * @param file 文件对象
 * @param allowedTypes 允许的MIME类型数组
 * @returns 是否允许
 */
export function validateFileType(file: File, allowedTypes: string[]): boolean {
  return allowedTypes.some(type => {
    if (type.endsWith('/*')) {
      const prefix = type.slice(0, -2)
      return file.type.startsWith(prefix)
    }
    return file.type === type
  })
}

/**
 * 验证文件大小
 * @param file 文件对象
 * @param maxSize 最大大小（字节）
 * @returns 是否允许
 */
export function validateFileSize(file: File, maxSize: number): boolean {
  return file.size <= maxSize
}

/**
 * 判断是否是图片文件
 * @param filename 文件名或MIME类型
 * @returns 是否是图片
 */
export function isImageFile(filename: string): boolean {
  const imageExtensions = ['jpg', 'jpeg', 'png', 'gif', 'bmp', 'webp', 'svg']
  const ext = getFileExtension(filename)
  return imageExtensions.includes(ext) || filename.startsWith('image/')
}

/**
 * 判断是否是文档文件
 * @param filename 文件名
 * @returns 是否是文档
 */
export function isDocumentFile(filename: string): boolean {
  const docExtensions = ['pdf', 'doc', 'docx', 'xls', 'xlsx', 'ppt', 'pptx', 'txt']
  const ext = getFileExtension(filename)
  return docExtensions.includes(ext)
}

/**
 * 获取文件图标类名
 * @param filename 文件名
 * @returns 图标类名
 */
export function getFileIcon(filename: string): string {
  const ext = getFileExtension(filename)
  
  // 图片
  if (isImageFile(filename)) return 'picture'
  
  // 文档
  const iconMap: Record<string, string> = {
    pdf: 'document',
    doc: 'document',
    docx: 'document',
    xls: 'tickets',
    xlsx: 'tickets',
    ppt: 'reading',
    pptx: 'reading',
    txt: 'document',
    zip: 'folder-opened',
    rar: 'folder-opened',
    '7z': 'folder-opened'
  }
  
  return iconMap[ext] || 'document'
}

/**
 * 读取文件为Base64
 * @param file 文件对象
 * @returns Promise<Base64字符串>
 */
export function readFileAsBase64(file: File): Promise<string> {
  return new Promise((resolve, reject) => {
    const reader = new FileReader()
    reader.onload = () => resolve(reader.result as string)
    reader.onerror = reject
    reader.readAsDataURL(file)
  })
}

/**
 * 下载文件
 * @param url 文件URL
 * @param filename 保存的文件名
 */
export function downloadFile(url: string, filename: string): void {
  const link = document.createElement('a')
  link.href = url
  link.download = filename
  link.style.display = 'none'
  document.body.appendChild(link)
  link.click()
  document.body.removeChild(link)
}

/**
 * 图片压缩配置
 */
export interface ImageCompressionOptions {
  maxWidth?: number
  maxHeight?: number
  quality?: number
}

/**
 * 压缩图片（使用Canvas）
 * @param file 图片文件
 * @param options 压缩选项
 * @returns Promise<压缩后的Blob>
 */
export function compressImage(file: File, options: ImageCompressionOptions = {}): Promise<Blob> {
  const {
    maxWidth = 1920,
    maxHeight = 1920,
    quality = 0.8
  } = options

  return new Promise((resolve, reject) => {
    const reader = new FileReader()
    reader.onload = (e) => {
      const img = new Image()
      img.onload = () => {
        let width = img.width
        let height = img.height

        // 计算缩放比例
        if (width > maxWidth || height > maxHeight) {
          const ratio = Math.min(maxWidth / width, maxHeight / height)
          width *= ratio
          height *= ratio
        }

        // 创建Canvas
        const canvas = document.createElement('canvas')
        canvas.width = width
        canvas.height = height
        const ctx = canvas.getContext('2d')
        
        if (!ctx) {
          reject(new Error('无法创建Canvas上下文'))
          return
        }

        // 绘制图片
        ctx.drawImage(img, 0, 0, width, height)

        // 转换为Blob
        canvas.toBlob(
          (blob) => {
            if (blob) {
              resolve(blob)
            } else {
              reject(new Error('图片压缩失败'))
            }
          },
          file.type,
          quality
        )
      }
      img.onerror = () => reject(new Error('图片加载失败'))
      img.src = e.target?.result as string
    }
    reader.onerror = () => reject(new Error('文件读取失败'))
    reader.readAsDataURL(file)
  })
}

